package com.hkd.common.security.service;

import com.hkd.common.core.constants.CacheConstants;
import com.hkd.common.core.constants.JwtConstants;
import com.hkd.common.core.enums.ResultCode;
import com.hkd.common.core.enums.UserIdentity;
import com.hkd.common.core.utils.JwtUtils;
import com.hkd.common.redis.service.RedisService;
import com.hkd.common.core.domain.LoginUser;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@Slf4j
@Service
public class TokenService {

    @Autowired
    private RedisService redisService;



    /**
     * 创建token
     * @param nickName 用户昵称
     * @param userId 用户id
     * @param secret 秘钥
     * @param identity 用户身份
     * @return String token
     */
    public String createToken(Long userId,String secret,Integer identity,String nickName) {

        //1、将用户id存入claims对象
        Map<String,Object> claims = new HashMap<>();
        claims.put(JwtConstants.LOGIN_USER_ID,userId);

        //利用秘钥和claims生成token
        String token = JwtUtils.createToken(claims, secret);

        //5、利用userKey保存用户的敏感信息到redis

        //key
        String redisKey = CacheConstants.LOGIN_TOKEN_KEY + userId;
        //value
        LoginUser loginUser = new LoginUser();
        loginUser.setIdentity(identity);
        loginUser.setNickName(nickName);

        redisService.setCacheObject(redisKey, loginUser, CacheConstants.EXP, TimeUnit.MINUTES);

        return token;
    }

    public String createToken(Long userId,String secret,Integer identity,String nickName,String headImage) {

        //1、将用户id存入claims对象
        Map<String,Object> claims = new HashMap<>();
        claims.put(JwtConstants.LOGIN_USER_ID,userId);

        //利用秘钥和claims生成token
        String token = JwtUtils.createToken(claims, secret);

        //5、利用userKey保存用户的敏感信息到redis

        //key
        String redisKey = CacheConstants.LOGIN_TOKEN_KEY + userId;
        //value
        LoginUser loginUser = new LoginUser();
        loginUser.setIdentity(identity);
        loginUser.setNickName(nickName);
        loginUser.setHeadImage(headImage);

        redisService.setCacheObject(redisKey, loginUser, CacheConstants.EXP, TimeUnit.MINUTES);

        return token;
    }

    /**
     * 延长token过期时间
     * @param token token
     * @param secret secret秘钥
     */

    public void extendToken(String token,String secret){
        //代码复用提取getUserKey
        String userKey = getUserId(token,secret);
        //校验 userKey
        if(userKey == null) return;

        String tokenKey = CacheConstants.LOGIN_TOKEN_KEY + userKey;

        Long expire = redisService.getExpire(tokenKey, TimeUnit.MINUTES);
        if(expire != null && expire < CacheConstants.REFRESH_TOKEN_TIME){
            log.info("延长token成功",tokenKey);
            redisService.expire(tokenKey, CacheConstants.EXP, TimeUnit.MINUTES);
        }
    }

    /**
     * 获取用户信息
     * @param token token
     * @param secret 秘钥
     * @return LoginUser 用户信息
     */
    public LoginUser getLoginUser(String token,String secret){
        //获取用户Id
        String userId = getUserId(token, secret);
        if(userId == null) {
            log.error("userId:{}", userId);
            return null;
        };
        //获取用户具体信息
        return redisService.getCacheObject(getTokenKey(userId), LoginUser.class);
    }

    public Boolean deleteLoginUser(String token, String secret) {
        //获取用户Id
        String userId = getUserId(token, secret);
        if(userId == null) {
            return null;
        };
        return redisService.deleteObject(getTokenKey(userId));

    }


    /**
     * 获取token key
     * @param userId 用户key
     * @return String token key
     */
    private String getTokenKey(String userId) {
        return CacheConstants.LOGIN_TOKEN_KEY + userId;
    }

    /**
     * 获取用户key
     * @param token token
     * @param secret secret秘钥
     * @return String 用户key
     */
    private String getUserId(String token,String secret){
        Claims claims = null;
        try{
            claims = JwtUtils.parseToken(token, secret);
            if(claims == null){
                log.warn(token, ResultCode.FAILED_TOKEN_PARSE);
                return null;
            }
        }catch (Exception e){
            log.warn(String.valueOf(e), ResultCode.FAILED_TOKEN_PARSE);
            return null;
        }

        return JwtUtils.getUserId(claims);
    }
    public Long getUserIdFT(String token,String secret){
        return Long.parseLong(getUserId(token,secret));
    }




}
